import * as THREE from 'three';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import CameraManager from '../managers/camera';
import {Howl, Howler} from 'howler';
import WebGLScene from './coreScenes/webglScene';
import Tween from '@tweenjs/tween.js';
import { setMehsUpToY } from '../utils/utils';
const opConfig = {
  "灯泡": {
    color1: '',
    color2: ''
  }
}
// const host = 'http://saas.beeaiot.cn/3dmodel';
const host = 'https://cdn.meos.center/k2g/bee';

const sound = new Howl({
  src: [host + '/xm3578.wav'],
  sprite: {
    open: [0, 1660],
    close: [2260, 1750],
    longopen: [0, 5000],
    longclose: [0, 5000]
  }
});
const Animations = {
  'A门': {
    open: {
      from: 0.0,
      to: 1.67
    },
    close: {
      from: 1.67,
      to: 3.34
    }
  },
  'B门': {
    open: {
      from: 5.0,
      to: 6.67
    },
    close: {
      from: 6.67,
      to: 8.35
    }
  },
  'C大门': {
    open: {
      from: 10.0,
      to: 15.00
    },
    close: {
      from: 15.0,
      to: 20.0
    }
  },
  'D大门': {
    open: {
      from: 20.0,
      to: 25.0
    },
    close: {
      from: 25.0,
      to: 30.0
    }
  },
  '蜜蜂': {
  },
}
const timeInterval = 1/7;
export default class BeeScene extends WebGLScene {
  constructor() {
    super();
    this.loadingManager = new THREE.LoadingManager();
    this.root = new THREE.Object3D();
    this.root.name = 'root';
    this.mixers = {};
    this.animations = [
      'A门',
      'C大门',
      'D大门'
    ];
    this.timePass = 0;
    this.colorIndex = 0;
    this.animTimes = {};
    this.animTo = {};
    this.Scene.add(this.root);
    const axesHelper = new THREE.AxesHelper( 10000 );
    // this.Scene.add( axesHelper );
  }

  Create() {
    if(this.load) return;
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    this.controls.minPolarAngle =  -Math.PI;
    this.controls.maxPolarAngle = Math.PI / 2;
    this.cameraManager = new CameraManager();
    this.cameraManager.camera = this.camera;
    this.cameraManager.controls = this.controls;
    this.fbxloader = new FBXLoader(this.loadingManager);
    this.createLightAndShadow();
    this.loadMeshes().then(() => {
      this.generalEventExecute({
        eventType: 'ready'
      });
    });
  }

  setBgColor(color) {
    this.Scene.background = new THREE.Color(color);
  }

  async loadMeshes() {
    await this.loadBeeHive().then(() => {
      
    }); // 蜂箱
    await Promise.allSettled([this.loadBee(), 
      this.loadGround(), this.loadBg()])
  }

  async loadBg() {
    const loader = new RGBELoader();
    loader.load( host + '/limpopo_golf_course_1k.hdr', ( texture ) => {

      texture.mapping = THREE.EquirectangularReflectionMapping;
      texture.needsUpdate = true;

      this.Scene.background = texture;
      this.Scene.environment = texture;

    } );

  }

  async loadScene() {
    const ground = await new Promise((resolve, reject) => {
      this.fbxloader.load(host + '/full_9_22_beehive_scene.fbx', (obj) => {
        console.log('ground', obj);
        resolve(obj);
      })
    })
    ground.position.y -= 100;
    this.root.add(ground);
  }

  async loadGround() {
    const ground = await new Promise((resolve, reject) => {
      this.fbxloader.load(host + '/map.fbx', (obj) => {
        console.log('ground', obj);
        resolve(obj);
      })
    })
    ground.position.y -= 100;
    this.root.add(ground);
  }

  async loadGreenTree() {
    const tree = await new Promise((resolve, reject) => {
      this.fbxloader.load(host + '/green_shrub.fbx', (obj) => {
        console.log('green', obj);
        resolve(obj);
      })
    })
    for(let i = 0; i < 100; i++){
      const newTree = tree.clone();
      newTree.position.x -= i * 100 + Math.random() * 100;
      newTree.position.z -= i * 100 + Math.random() * 100;
      this.root.add(newTree);
    }
  }

  async loadFlower() {
    const tree = await new Promise((resolve, reject) => {
      this.fbxloader.load(host + '/yellow_flower.fbx', (obj) => {
        console.log('flower', obj);
        resolve(obj);
      })
    })
    for(let i = 0; i < 100; i++){
      const newTree = tree.clone();
      newTree.position.x -= i * 100 + Math.random() * 100;
      newTree.position.z -= i * 100 + Math.random() * 100;
      this.root.add(newTree);
    }
  }

  async loadTree() {
    const tree = await new Promise((resolve, reject) => {
      this.fbxloader.load(host + '/tree.fbx', (obj) => {
        console.log('tree', obj);
        resolve(obj);
      })
    })
    for(let i = 0; i < 5; i++){
      const newTree = tree.clone();
      newTree.position.x -= i * 900 + Math.random() * 100;
      newTree.position.z -= i * 200 + Math.random() * 100;
      this.root.add(newTree);
    }
  }
  // 加载蜜蜂
  async loadBee() {
    console.log(41);
    const bee = await new Promise((resolve, reject) => {
      this.fbxloader.load(host + '/bee.fbx', (obj) => {
        console.log('bee', obj);
        resolve(obj);
      })
    })
    this.mixers['蜜蜂'] = new THREE.AnimationMixer(bee);
    this.mixers['蜜蜂'].clipAction(bee.animations[0]).play();
    this.root.add(bee);
  }
  async loadBeeHive() {
    console.log(4);
    const objects = await new Promise((resolve, reject) => {
      this.fbxloader.load(host + '/beehive.fbx', (obj) => {
        console.log(obj);
        resolve(obj);
      })
    })
    console.log(objects);
    for(let key of this.animations){
      this.mixers[key] = new THREE.AnimationMixer(objects.getObjectByName(key));
      this.mixers[key].clipAction(objects.animations[0]).play();
    }
    objects.traverse(obj => {
      try{
         if(obj.isMesh && obj.material && !obj.material.isMeshStandardMaterial){
          if(Array.isArray(obj.material)){
             obj.material = obj.material.map(r => {
              return new THREE.MeshStandardMaterial({
                color: r.color,
                map: r?.map ?  r?.map?.clone() : undefined
              })
             })
          }else{
             obj.material = new THREE.MeshStandardMaterial({
              color: obj.material.color,
              map: obj.material?.map ?  obj.material?.map?.clone() : undefined
            })
          }
         
        }
      }catch(er){
        console.log(obj)
        console.log(er);
      }
    })
    
    
    this.root.add(objects);
    const box = new THREE.Box3();
    box.setFromObject(objects);
    this.mainBuildingSize = new THREE.Vector3(box.max.x - box.min.x, box.max.y - box.min.y, box.max.z - box.min.z);
    this.mainBuildingCenter = new THREE.Vector3(0,0,0)

    box.getCenter(this.mainBuildingCenter);
    const helper = new THREE.Box3Helper( box, 0xffff00 );
    // this.root.add(helper)

    const radiusTimes = (this.mainBuildingSize.y / Math.max(this.mainBuildingSize.x, this.mainBuildingSize.z));
    this.radiusTimes = radiusTimes > 1 ? 1.5 * radiusTimes : 2.5 * radiusTimes;
    /** 漫游的所在高度，除以建筑高度的倍数 */
    this.heightTimes = 0.7;
    this.setCamera();
    return objects;
  } 

  setCamera() {
    let radius = Math.max(this.mainBuildingSize.x, this.mainBuildingSize.z) * this.radiusTimes,
            y = (this.mainBuildingSize.y * 0.5 + this.mainBuildingCenter.y) * this.heightTimes;
    const hudu = THREE.MathUtils.degToRad(-60),
                    x = this.mainBuildingCenter.x + Math.sin(hudu) * radius,
                    z = this.mainBuildingCenter.z + Math.cos(hudu) * radius;
    const position = new THREE.Vector3(x, y, z);
    this.camera.position.copy(position);
    this.controls.target.set(this.mainBuildingCenter.x, this.mainBuildingCenter.y, this.mainBuildingCenter.z);
    const max = Math.max(this.mainBuildingSize.x, this.mainBuildingSize.y, this.mainBuildingSize.z);
    this.controls.minDistance = max;
    this.controls.maxDistance = max * 3;
    this.controls.saveState();
    this.controls.update();
  }

  restoreCamera() {
    this.controls.reset();
  }

  initGui() {
    const gui = new GUI();
  }

  createLightAndShadow() {
    /** ************************  灯光调试  *********************************** */
    // 平行光 配置
    const power = 1.0;
    // 环境光
    this.amlight = new THREE.AmbientLight(0xFFFFFF, 4.5);
    this.amlight.up.set(0, 1, 0);
    this.Scene.add(this.amlight);

    this.light1 = new THREE.DirectionalLight(0xFFFFFF, 1.0);
    this.light1.position.set(0, 100, 100);
    this.light1.target.position.set(0, 0, 0);
    this.light1.updateMatrixWorld();
    this.Scene.add(this.light1);

    this.light2 = new THREE.DirectionalLight(0xFFFFFF, 1.0);
    this.light2.position.set(0, 200, -200);
    this.light2.target.position.set(0, 0, 0);
    this.light2.updateMatrixWorld();
    this.Scene.add(this.light2);
  }
  openDoor(objName) {
    if(objName.match(/[CD]/gi)){
       sound.play('longopen')
    }else{
       sound.play('open')
    }
   
    this.animTimes[objName] = Animations[objName].open.from;
    this.animTo[objName] = Animations[objName].open.to;
  }
  closeDoor(objName) {
     if(objName.match(/[CD]/gi)){
       sound.play('longopen')
    }else{
       sound.play('close')
    }
    this.animTimes[objName] = Animations[objName].close.from;
    this.animTo[objName] =  Animations[objName].close.to;
  }
  turnAC(status) {
    const obj = this.root.getObjectByName('空调指示灯');
    if(status === 'on'){
      obj.material.color = new THREE.Color(26/255,255/255,15/255);
    }else if(status === 'off'){
      obj.material.color = new THREE.Color(255/255,255/255,255/255);
    }else if(status == 'cold'){
      obj.material.color = new THREE.Color(15/255,86/255,199/255);
    }else if(status == 'hot'){
      obj.material.color = new THREE.Color(288/255,50/255,15/255);
    }
  }
  turnAlarm(status) {
    const obj = this.root.getObjectByName('报警灯');
    this.alarmObj = obj
    if(status === 'on'){
      this.alarmOn = true;
      this.timePass = 0;
      obj.material.color = new THREE.Color(255/255,0,0);
    }else if(status === 'off'){
      this.alarmOn = false;
      obj.material.color = new THREE.Color(255/255,255/255,255/255);
    }
  }
  turnLight(status) {
    const obj = this.root.getObjectByName('灯泡');
    if(status === 'on'){
      obj.material.color = new THREE.Color(238/255,255/255,50/255);
    }else if(status === 'off'){
      obj.material.color = new THREE.Color(255/255,255/255,255/255);
    }
  }
  Update() {
      this.delta = this.clock.getDelta();
      if (!this.load && this.renderer) {
          this.renderer.render(this.Scene, this.camera);
      }
      for(let key of this.animations){
        if(this.mixers[key]){
          if(this.animTimes[key] < this.animTo[key]){
            this.animTimes[key] += this.delta;
            this.mixers[key].setTime(this.animTimes[key]);
          }
        }
      }
      if(this.mixers['蜜蜂']){
        this.mixers['蜜蜂'].update(this.delta);
      }
      if (this.cameraManager && this.cameraManager.isMoving) {
          this.cameraManager.Update();
      }
      if(this.alarmOn && this.alarmObj){
        if(this.timePass > timeInterval){
          console.log(this.timePass);
          this.timePass = 0;
          if(this.colorIndex === 0){
            this.colorIndex = 1;
            this.alarmObj.material.color = new THREE.Color(255/255,255/255,255/255);
          }else{
            this.colorIndex = 0;
            this.alarmObj.material.color = new THREE.Color(255/255,0,0);
          }
        }
        this.timePass += this.delta;
      }
      this.controls.update();
  }
  _ResetScene() {
      this.load = false;
  }

  Destroy() {
      if (this.Scene) {
          this._ResetScene();
          this.Scene.children.map(c => {
              this.destroyChild(c);
              c.clear();
          });
          // 清除场景全部child
          this.Scene.clear();
      }
      if (this.renderer) {
          // 卸载场景
          this.renderer.renderLists.dispose();
          this.renderer.dispose();
      }
  }
}